package com.extremelylargepackage.sprite;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Color;

public class CollidableSprite extends AbstractSprite {
	private boolean[][] _alphaMask;
	public Bitmap _solid;

	/**
	 * Specifies the minimum alpha channel value for inclusion in detecting collisions.
	 */
	private static final int ALPHA_THRESHOLD = 128;

	public CollidableSprite(Bitmap b) 
	{
		_sprite = b;
		_alphaMask = generateAlphaMask(b);
		//_solid = createImageFromMask();
	}
	
//	@Override
//	public Bitmap getBitmap()
//	{
//		return _solid;
//	}

	private boolean[][] generateAlphaMask(Bitmap b)
	{
		int width = b.getWidth();
		int height = b.getHeight();

		boolean[][] res = new boolean[width][height];
		int[] colors = new int[width * height];
		b.getPixels(colors, 0, width, 0, 0, width, height);

		for(int x = 0; x < width; ++x) {
			for(int y = 0; y < height; ++y) {
				// for every line we go down, we move "width" cells along in the colors[] array, plus x
				int cell = y * width + x;
				int alpha = Color.alpha(colors[cell]);
				res[x][y] = alpha > ALPHA_THRESHOLD;
			}
		}

		return res;
	}

	/**
	 * Determines whether this sprite is colliding with another sprites, given each are at the
	 * specified locations.
	 * @param thisX
	 * @param thisY
	 * @param other
	 * @param otherX
	 * @param otherY
	 * @return true if colliding, false otherwise
	 */
	public boolean collidesWith(float thisX, float thisY, CollidableSprite other, float otherX, float otherY) {
		//Check to see if the rectangles bounding each entity's sprite overlap.
		if(thisX > otherX + other.getWidth())
			return false;
		if(thisX + this.getWidth() < otherX)
			return false;
		if(thisY > otherY + other.getHeight())
			return false;
		if(thisY + this.getHeight() < otherY)
			return false;
		// Determine the area (relative to each bitmap) of the overlap

		// x and y of overlapping area relative to upper left corner
		// If e is to the right of this, overlapping area starts at the difference in x's
		// Otherwise, overlapping area starts at left edge. Same for y.
		int thisOverlapX = (int)Math.max(otherX - thisX, 0);
		int thisOverlapY = (int)Math.max(otherY - thisY, 0);
		int eOverlapX = (int)Math.max(thisX - otherX, 0); // analogous to thisOverlapX and Y
		int eOverlapY = (int)Math.max(thisY - otherY, 0);

		// width and height of overlapping area
		// The relative x location of the right edge of the overlap is whichever is further
		// to the left between the right edge of e and the right edge of this. Subtract the
		// relative x location of where the overlapping area starts from the location where
		// the overlapping area ends to find the width.
		int overlapW = (int)Math.min(otherX + other.getWidth() - thisX, this.getWidth()) - thisOverlapX;
		int overlapH = (int)Math.min(otherY + other.getHeight() - thisY, this.getHeight()) - thisOverlapY;

		// Go through both alpha masks, and if at any location both masks are on (true), commence collision
		boolean[][] thisAlphaMask = this._alphaMask;
		boolean[][] eAlphaMask = other._alphaMask;
		for(int xOff = 0; xOff < overlapW; ++xOff) 
		{	
			for(int yOff = 0; yOff < overlapH; ++yOff) 
			{
				if(thisAlphaMask[xOff + thisOverlapX][yOff + thisOverlapY] && eAlphaMask[xOff + eOverlapX][yOff + eOverlapY])
					return true;
			}
		}

		return false;
	}
	
	private Bitmap createImageFromMask()
	{
		int[] colors = new int[_alphaMask.length * _alphaMask[0].length];
		for(int x = 0; x < _alphaMask.length; ++x)
		{
			for(int y = 0; y < _alphaMask[x].length; ++y)
			{
				if(_alphaMask[x][y])
					colors[y * _alphaMask.length + x] = Color.WHITE;
				else
					colors[y * _alphaMask.length + x] = Color.TRANSPARENT;
			}
		}
		return Bitmap.createBitmap(colors, _alphaMask.length, _alphaMask[0].length, Config.ARGB_8888);
	}
}
